package com.tangsm.spring.mvc.mybatis.controller;

import com.github.pagehelper.PageInfo;
import com.tangsm.spring.mvc.mybatis.domain.dto.AppointExecution;
import com.tangsm.spring.mvc.mybatis.domain.dto.Result;
import com.tangsm.spring.mvc.mybatis.domain.entity.Book;
import com.tangsm.spring.mvc.mybatis.enums.AppointStateEnum;
import com.tangsm.spring.mvc.mybatis.exception.NoNumberException;
import com.tangsm.spring.mvc.mybatis.exception.RepeatAppointException;
import com.tangsm.spring.mvc.mybatis.service.BookService;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 书籍管理控制器
 * @author tangsm
 * @date 2021-08-02 11:48:00
 */
@Controller
@RequestMapping("/book")
public class BookController {

	private static final Logger log = LoggerFactory.getLogger(BookController.class);

	@Autowired
	private BookService bookService;

	/**
	 * 分页查询
	 * @param pageNum 页码
	 * @param pageSize 每页数
	 * @return 分页对象
	 */
	@ResponseBody
	@GetMapping("/page/{pageNum}/{pageSize}")
	public PageInfo<Book> page(@PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize) {
		return bookService.page(pageNum, pageSize);
	}

	/**
	 * 书籍管理页面入口
	 * @return 跳转页面路径
	 */
	@GetMapping("/main")
	public String main(Model model, HttpServletRequest request){
		log.debug("欢迎[{}]进去book管理主页", request.getParameter("userName"));
		List<Book> list = bookService.getList();
		model.addAttribute("list", list);
		return "book/book-main";
	}

	/**
	 * 查询所有书籍信息
	 * @return 通用结果
	 */
	@ResponseBody
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public Result<List<Book>> list() {
		List<Book> list = bookService.getList();
		return new Result<>(true, list);
	}

	/**
	 * 新增图书
	 * @param book
	 * @return
	 */
	@ResponseBody
	@PostMapping("/add")
	public Result<Book> add(@RequestBody @Valid Book book){
//		StringBuilder errors = new StringBuilder();
//
//		ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
//		Validator validator = validatorFactory.getValidator();
//
//		Set<ConstraintViolation<Book>> constraintViolations = validator.validate(book);
//
//		if(constraintViolations != null && !constraintViolations.isEmpty()){
//			constraintViolations.forEach(s -> errors.append(s.getMessage()).append("</br>"));
//			return new Result<>(false, errors.toString());
//		}

		return new Result<>(true, book);
	}

	/**
	 * 打开书籍详情页面
	 * @param bookId 书籍ID
	 * @param model 页面模型
	 * @return 书籍详情路径
	 */
	@RequestMapping(value = "/detail/{bookId}", method = RequestMethod.GET)
	public String detail(@PathVariable("bookId") Long bookId, Model model) {
		if (bookId == null) {
			return "book/book-main";
		}
		Book book = bookService.getById(bookId);
		if (book == null) {
			return "book/book-main";
		}
		model.addAttribute("book", book);
		return "book/book-detail";
	}

	/**
	 * 预约书籍
	 * @param bookId 书籍ID
	 * @param studentId 学生学号
	 * @return 通用结果
	 */
	@ResponseBody
	@PostMapping("/appoint/{bookId}")
	public Result<AppointExecution> appoint(@PathVariable("bookId") Long bookId,
                                            @RequestParam("studentId") Long studentId) {
		if (studentId==null) {
			return new Result<>(false, "学号不能为空");
		}
		AppointExecution execution = null;
		try {
			execution = bookService.appoint(bookId, studentId);
		} catch (NoNumberException e1) {
			execution = new AppointExecution(bookId, AppointStateEnum.NO_NUMBER);
		} catch (RepeatAppointException e2) {
			execution = new AppointExecution(bookId, AppointStateEnum.REPEAT_APPOINT);
		} catch (Exception e) {
			execution = new AppointExecution(bookId, AppointStateEnum.INNER_ERROR);
		}
		return new Result<>(true, execution);
	}

}
